/* sprite.vala
 *
 * Copyright (C) 2010, 2011  Richard Talbot-Watkins
 * Copyright (C) 2010, 2011  Dave Jeffery
 * 
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * Authors:
 *  Richard Talbot-Watkins <richtw1@gmail.com>
 * 	Dave Jeffery <david.richard.jeffery@gmail.com>
 */

/**
 * This class is the data model for the sprites.
 *
 * @author Richard Talbot-Watkins <richtw1@gmail.com>
 * @author Dave Jeffery <david.richard.jeffery@gmail.com>
 * @version 2011.0103
 * @since 0.1
 */
public class BeebSpriter.Sprite : GLib.Object {
	/**
	 * Signal emitted when changed.
	 */
	public signal void changed ();

	/**
	 * Sprite name property. 
	 */
	private string _name;

	/**
	 * Default name for unnamed sprites.
	 */
	private static const string UNNAMED_SPRITE =  _("Untitled");

	/**
	 * Getter/Setter for the Sprite name property.
	 */
	public string name { 
		get {
			return _name;
		}
 
		set {
			if (_name != value) {
				_name = (value == "") ? UNNAMED_SPRITE : value;

				/* Emit changed signal. */
				changed ();
			}
		}
	}

	/* Sprite width (in pixels). */
	public int width { get; set; }

	/* Sprite height (in pixels). */
	public int height { get; set; }

	/* Sprite data stored as indexed data (one byte per pixel). */
	public uint8[] bitmap { get; set; }

	/* Palette for sprite. */
	public BeebPalette.Colour[] palette { get; set; }

	/**
	 * Normal constructor function for Sprite class.
	 *
	 * @param name Appears under sprite in sprite sheet window.
	 * @param width Width of sprite in (BBC Micro) pixels.
	 * @param height Height of sprite in (BBC Micro) pixels.
	 * @param palette Palette used to display this sprite in sprite sheet.
	 */
	public Sprite (string name, int width, int height, 
									BeebPalette.Colour[] palette) {
		this.name = name;
		this.width = width;
		this.height = height;
		this.bitmap = new uint8[width * height];
		this.palette = palette;
	}

	/**
	 * Special constructor for creating copies of Sprite instances.
	 *
	 * Arrays are copied by reference, so each element needs to be copied
	 * individually. I can't seem to use foreach for doing this.
	 *
	 * @param name Appears under sprite in sprite sheet window.
	 * @param to_copy Sprite copied to create a new instance.
	 */
	public Sprite.from_copy (string name, Sprite to_copy) {
		this.name = name;
		this.width = to_copy.width;
		this.height = to_copy.height;

		/* Copy the bitmap data by value. */
		var source_bitmap = to_copy.bitmap;
		var size = to_copy.width * to_copy.height;
		this.bitmap = new uint8[size];
		for (int b = 0; b != size; ++b) {
			this.bitmap[b] = source_bitmap[b];
		}
		
		/* Copy the palette data by value. */
		var source_palette = to_copy.palette;
		var palette_size = source_palette.length;
		this.palette = new BeebPalette.Colour[palette_size];
		for (int c = 0; c != palette_size; ++c) {
			this.palette[c] = to_copy.palette[c];
		}
	}

	/**
	 * Returns the bitmap data in RGBA format, suitable for creating Pixbufs.
	 *
	 * @return A uchar[] array that can be used as a Pixbuf data source.
	 */
	public uchar[] get_as_rgba () {
		uchar[] rgba = {};
		foreach (var byte in bitmap) {
			var colour = Rgba (0, 0, 0, 0);
			if (byte != 0xff) {
				colour = palette[byte].get_as_rgba ();
			}
			rgba += (uchar) colour.red;
			rgba += (uchar) colour.green;
			rgba += (uchar) colour.blue;
			rgba += (uchar) colour.alpha;
		}

		return rgba;
	}

	/**
	 * Special to_string function for this class.
	 *
	 * @return A string containing the Sprite instance's name property.
	 */
	public string to_string () {
		return name ?? UNNAMED_SPRITE;
	}
}
